package com.github.boluo1230.wechat.util;

import com.github.boluo1230.wechat.util.crypto.MD5;
import com.google.common.collect.Maps;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.*;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.swing.text.html.Option;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by HUHAIYANG on 2017/6/7.
 */
@Component
public class WeixinUtil {

    public static List<String> getMessageSignatureList(HttpServletRequest request, String signToken) {
        List<String> paramList = new ArrayList<>();
        paramList.add(signToken);
        paramList.add(request.getParameter("timestamp"));
        paramList.add(request.getParameter("nonce"));
        return paramList;
    }

    public static boolean checkSignature(String signature, List<String> paramList) {
        if (StringUtils.isBlank(signature)) {
            return false;
        }
        Collections.sort(paramList);
        StringBuilder sign = new StringBuilder();
        for (String param : paramList) {
            sign.append(param);
        }
        String sha1Signature = DigestUtils.sha1Hex(sign.toString());
        return signature.equals(sha1Signature);
    }

//    /**
//     * xml转map 不带属性
//     *
//     * @param xmlStr
//     * @param needRootKey 是否需要在返回的map里加根节点键
//     * @return
//     * @throws DocumentException
//     */
//    public static Map xmlToMap(String xmlStr, boolean needRootKey) throws DocumentException {
//        Document doc = DocumentHelper.parseText(xmlStr);
//        Element root = doc.getRootElement();
//        Map<String, Object> map = (Map<String, Object>) xmlToMap(root);
//        if (root.elements().size() == 0 && root.attributes().size() == 0) {
//            return map;
//        }
//        if (needRootKey) {
//            //在返回的map里加根节点键（如果需要）
//            Map<String, Object> rootMap = new HashMap<String, Object>();
//            rootMap.put(root.getName(), map);
//            return rootMap;
//        }
//        return map;
//    }
//
//    /**
//     * xml转map 不带属性
//     *
//     * @param element
//     * @return
//     */
//    private static Object xmlToMap(Element element) {
//        // System.out.println(element.getName());
//        Map<String, Object> map = new LinkedHashMap<String, Object>();
//        List<Element> elements = element.elements();
//        if (elements.size() == 0) {
//            map.put(element.getName(), element.getText());
//            if (!element.isRootElement()) {
//                return element.getText();
//            }
//        } else if (elements.size() == 1) {
//            map.put(elements.get(0).getName(), xmlToMap(elements.get(0)));
//        } else if (elements.size() > 1) {
//            // 多个子节点的话就得考虑list的情况了，比如多个子节点有节点名称相同的
//            // 构造一个map用来去重
//            Map<String, Element> tempMap = new LinkedHashMap<String, Element>();
//            for (Element ele : elements) {
//                tempMap.put(ele.getName(), ele);
//            }
//            Set<String> keySet = tempMap.keySet();
//            for (String string : keySet) {
//                Namespace namespace = tempMap.get(string).getNamespace();
//                List<Element> elements2 = element.elements(new QName(string, namespace));
//                // 如果同名的数目大于1则表示要构建list
//                if (elements2.size() > 1) {
//                    List<Object> list = new ArrayList<Object>();
//                    for (Element ele : elements2) {
//                        list.add(xmlToMap(ele));
//                    }
//                    map.put(string, list);
//                } else {
//                    // 同名的数量不大于1则直接递归去
//                    map.put(string, xmlToMap(elements2.get(0)));
//                }
//            }
//        }
//        return map;
//    }

    public static Map<String, String> xmlString2Map(String xml) {
        Map<String, String> map = Maps.newTreeMap();
        Document doc;
        try {
            doc = DocumentHelper.parseText(xml); // 将字符串转为XML
            Element rootElt = doc.getRootElement(); // 获取根节点
            @SuppressWarnings("unchecked")
            List<Element> list = rootElt.elements();// 获取根节点下所有节点
            for (Element element : list) { // 遍历节点
                map.put(element.getName(), element.getText()); // 节点的name为map的key，text为map的value
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    public static String charsetConvert(String result) {
        try {
            return new String(result.getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 签名校验(规则与微信支付规则一样)
     */
    public static boolean checkSignature(Map<String, String> param, String token, String key) {
        try {
            StringBuilder sign = new StringBuilder();
            for (Map.Entry<String, String> entry : param.entrySet()) {
                sign.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "utf-8")).append("&");
            }
            sign = new StringBuilder(sign.toString().substring(0, sign.length() - 1));
            sign.append("&key=").append(key);
            String signStr = MD5.encrypt(sign.toString()).toUpperCase();
            return signStr.equals(token);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}

